﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Phoenix.Xna.Framework;
using Phoenix.Xna.Framework.ContentPipeline;
using Phoenix.Xna.Framework.Graphics;
using System.Windows;

namespace Phoenix.Xna.Framework.Presentation
{
    public class EffectParameterWrapper : DependencyObject
    {
        private EffectParameter _parameter;
        private Type _type;

        public bool Serialize { get; set; }
        public string Name
        {
            get { return _parameter.Name; }
        }
        public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(object), typeof(EffectParameterWrapper));
        public object Value
        {
            get { return (object)GetValue(ValueProperty); }
            set { SetValue(ValueProperty, value); }
        }
        public string ValueType { get; private set; }

        public EffectParameterWrapper(EffectParameter parameter)
        {
            _parameter = parameter;
            ParseParameterType(_parameter);

            if (_type != null)
            {
                if(_type == typeof(Texture) || _type == typeof(Texture2D))
                {
                    Value = string.Empty;
                }
                else
                {
                    Value = StringHelper.ObjectToString(Activator.CreateInstance(_type.Assembly.FullName, _type.FullName).Unwrap());
                }
            }
        }

        public bool IsType<T>()
        {
            return (_type == typeof(T));
        }

        public ParameterBinding GenerateBinding()
        {
            ParameterBinding b = new ParameterBinding()
            {
                ID = Name,
                Parameter = Name
            };

            if (ContentHelper.IsLoadableType(_type))
            {
                b.MetaData = Value.ToString();
            }
            else
            {
                b.Value = Value.TypeConvertionCast(_type);
            }

            return b;
        }

        private void ParseParameterType(EffectParameter p)
        {
            switch (p.ParameterClass)
            {
                case EffectParameterClass.MatrixColumns:
                    break;
                case EffectParameterClass.MatrixRows:
                    if (p.RowCount == 4 && p.ColumnCount == 4)
                    {
                        ValueType = "Matrix";
                        _type = typeof(Matrix);
                    }
                    else
                    {
                        ValueType = "Unsupported";
                    }
                    break;
                case EffectParameterClass.Object:
                case EffectParameterClass.Scalar:
                    ParseParameterType(p.ParameterType);
                    break;
                case EffectParameterClass.Struct:
                    break;
                case EffectParameterClass.Vector:
                    if (p.ColumnCount >= 2 && p.ColumnCount <= 4)
                    {
                        ValueType = string.Format("Vector{0}", p.ColumnCount);

                        switch (p.ColumnCount)
                        {
                            case 2:
                                _type = typeof(Vector2);
                                break;
                            case 3:
                                _type = typeof(Vector3);
                                break;
                            case 4:
                                _type = typeof(Vector4);
                                break;
                        }
                    }
                    else
                    {
                        ValueType = "Unsupported";
                    }
                    break;
                default:
                    ValueType = "Unsupported";
                    break;
            }

        }

        private void ParseParameterType(EffectParameterType type)
        {
            switch (type)
            {
                case EffectParameterType.Bool:
                    ValueType = "bool";
                    _type = typeof(bool);
                    break;
                case EffectParameterType.Int32:
                    ValueType = "int";
                    _type = typeof(int);
                    break;                
                case EffectParameterType.Single:
                    ValueType = "float";
                    _type = typeof(int);
                    break;
                case EffectParameterType.String:
                    ValueType = "string";
                    _type = typeof(string);
                    break;
                case EffectParameterType.Texture:
                    ValueType = "Texture2D";
                    _type = typeof(Texture2D);
                    break;
                case EffectParameterType.Texture2D:
                    ValueType = "Texture2D";
                    _type = typeof(Texture2D);
                    break;
                default:
                    ValueType = "Unsupported";
                    _type = null;
                    break;
            }
        }
    }
}
